# MikroTik - Guest Wifi with Limited Bandwidth John Simpson `` 2016-10-14 This documents how I was able to set up my MikroTik router with a "guest wifi" network, and then limit its total bandwidth to 1MBit, so that ~~if~~when the nosy neighbors' kids find it, they won't be tempted to abuse it. * MikroTik hAP ac (RouterBOARD 962UiGS-5HacT2HnT) * RouterOS version 6.37.1 ## Planning Before you begin, you need to plan out a few details. * **The SSID (aka "network name") and password (if any)** for the new guest network. I do not recommend having a guest network without encryption (and therefore without a password), simply because in many places, you can be held legally responsible for what other people do on your network. * **The IP range** you're going to use for the new guest network. In this write-up I'm using `192.168.0.0/24` as the guest network, with `192.168.0.1` as the router's address within that network. If you're like me and you you tinker with your router on a regular basis, you may care what the interface names are, so it wouldn't hurt to decide on those as well. * **The name(s) of your existing wirless interface(s).** If you have a dual-band router, which interface is in which band (i.e. 2.4 GHz or 5 GHz.) * **Information about your other network(s).** I have three other "internal" networks, having a list of the interfaces and IP addresses involved was helpful. ## Firewall Rules Before we do *anything*, we need to be sure that the new guest network won't be able to reach your normal internal network, and (to a lesser extent) vice-versa. I actually have two separate internal networks - a "work" network which supports IPv6, and a "home" network which does not. I get my IPv6 addresses from a [Hurricane Electric tunnel](https://tunnelbroker.net), which means that Netflix accuses me of using a proxy if IPv6 is involved... so the streaming boxes are on the "home" network, where they *can't* use IPv6. These two networks "trust" each other, but the other non-external networks (the guest network we're setting up in this document, and another network which stays connected to a VPN at work) are not allowed to access the "trusted" networks, or vice-versa. In my router, these are the rules which allow the "trusted" networks to talk to each other. ``` /interface list add name=trusted /interface list member add list=trusted interface=internal /interface list member add list=trusted interface=home /ip firewall filter add \ chain=forward \ in-interface-list=trusted \ out-interface-list=trusted \ action=accept \ comment="FORWARD: trusted networks may speak with each other" ``` This rule, which comes right AFTER the rule above, prevents any other non-external networks from sending traffic to any interface *other than* the external interface, which prevents them from talking to each other. ``` /ip firewall filter add \ chain=forward \ out-interface=!ether1 \ action=reject \ reject-with=icmp-network-unreachable \ log=yes \ comment="FORWARD: no traffic between non-trusted internal networks" ``` If you don't have separate "internal" networks which need to trust each other, then this last rule should be all you need. ## Create Guest Wifi ### Wireless Security Profile The first step is to create a security profile, which sets the encryption type and password which will be used on the new network(s). > Note that WPA2 keys must be a *minimum* of eight characters long. ``` /interface wireless security-profiles add name=GUEST \ mode=dynamic-keys \ authentication-types=wpa2-psk \ wpa2-pre-shared-key="guest-password" ``` If you want your new network to *not* use encryption, and therefore not require a password, the command looks like this: ``` /interface wireless security-profiles add name=GUEST \ mode=none ``` Be careful if you do this. * If somebody uses your guest network to do something illegal, it will be traced back to your IP address, and there's a good chance you would be blamed for whatever they did. * People on your guest network are using the same internet connection as your normal network. If your connection is metered, your guests' usage counts towards your total. And if your connection is speed-limited, guests will use part of that bandwidth, leaving less available for you. ### Wireless Interface(s) If you have a single-band router, make sure you know the name of your wifi interface. For a dual-band router, make sure you know which interface is 2.4 GHz and which one is 5 GHz. ``` /interface wireless print where !master-interface Flags: X - disabled, R - running 0 R name="wlan1" ... band=2ghz-b/g/n ... 1 R name="wlan2" ... band=5ghz-a/n/ac ... ``` > In this example, `wlan1` is the 2.4 GHz interface, and `wlan2` is the 5 GHz interface. Create the new Wifi interface. If you have a dual-band router and want your guest SSID to exist on both bands, create an interface for each band. Note that the SSIDs should be different, in order to avoid confusion. ``` /interface wireless add name=wlan24-guest \ master-interface=wlan1 \ ssid=GUEST-24 \ security-profile=GUEST add name=wlan5-guest \ master-interface=wlan2 \ ssid=GUEST-5 \ security-profile=GUEST ``` ### Bridge Interface Now that the wireless interfaces exist, we need to bridge them together so we can manage them as a single interface. Note that if you have a single-band router, you don't really *need* a bridge, unless you want to be able to add an ethernet, VPN, or other interface as part of the guest network. If you're not going to use a bridge, you can skip this step, and wherever you see the `guest-bridge` interface below (i.e. setting its IP address, setting up the DHCP server, etc.) you should use the name of the guest wifi interface (such as `wlan24-guest`) instead. ``` /interface bridge add name=guest-bridge /interface bridge ports add bridge=guest-bridge interface=wlan24-guest add bridge=guest-bridge interface=wlan5-guest ``` ### IP Address Now we can set the router's IP address for the guest network. (Again, if you're not using a bridge, you should use the name of the wireless interface here.) ``` /ip address add interface=guest-bridge \ address=192.168.0.1/24 ``` ### DNS Server The router is going to be acting as the DNS server for the guest network, so we should allow queries. The router's DNS server forwards any queries it receives to whatever DNS servers it was told to use by the DHCP server who assigned its external address, and caches those results (so that if the same name is queried multiple times, there's only one query to the "upstream" DNS servers.) ``` /ip dns set allow-remote-requests=yes ``` ### DHCP Server People connecting to the guest network will need a DHCP server in order to get an IP address and other networking information. The router will provide this service. First create a pool of IPs which may be assigned to guests. These must be within the guest network's IP space, and must *not* include the router's IP. (I generally use `.100` through `.199` within each network for this.) ``` /ip pool add name=guest-pool ranges=192.168.0.100-192.168.0.199 ``` Next, set up the options which will be sent to DHCP clients connecting to the new network. ``` /ip dhcp-server network add address=192.168.0.0/24 \ gateway=192.168.0.1 \ netmask=24 \ dns-server=192.168.0.1 ``` Finally, we can start the DHCP server for the guest network. ``` /ip dhcp-server add name=guest \ interface=guest-bridge \ address-pool=guest-pool \ authoritative=yes ``` ### Test At this point, you should be able to use a phone, tablet, laptop, or other device, and see the new Wifi network. You should be able to connect to the guest wifi, and be able to "get out" to the rest of the internet. ## Limit the Bandwidth With a "wide open" guest network, there's a pretty good chance that random people are going to connect to your network. One of the dangers is that "guests" will download or upload a bunch of large files, or stream a bunch of video, or otherwise use up so much bandwidth that it interferes with *your* use of your network. One thing you can do to minimize the damage is to limit the speed of the traffic on the guest network. By choosing a limit which makes high-bandwidth usage inconvenient, but allows "normal" use (email, chat, typical web pages), you can make your guest network a less inviting target for random people to use. ### Create the queue to limit traffic RouterOS uses a queueing mechanism to impose limits on traffic. There are a few different ways it can do this, I'm going with the simplest option. ``` /queue simple add name=guest-queue \ target=192.168.0.0/24 \ max-limit=1M/1M ``` The limits are specified as two numbers, separated by a `/`. The first number is the upload limit (i.e. how much traffic the guest network can upload to the internet), and the second one is the download limit (i.e. how much the traffic the guest network can download from the internet.) The numbers are "bits per second", and can be followed by `k`, `M`, or `G` as needed (i.e. `1M` is the same as `1048576`.) ### Bypass fasttrack for guest traffic Having the queue in place *should* be enough to work, however RouterOS has this thing called "fasttrack", which is a way to move packets from one interface to another as quickly as possible. It does this by making the routing engine bypass several steps, including the queueing mechanism. This means that traffic which is fasttrack'ed cannot be controlled by the queueing mechanism. The fasttrack mechanism is invoked by an `/ip firewall filter` rule with the clause `action=fasttrack-connection`. If a packet matches the conditions for a rule *before* this one, that rule's `action` will be followed. If the action is one which ends the firewall processing (i.e. `accept`, `drop`, `reject`, etc.) the fasttrack rule will never be reached, and the queueing mechanism will be able to slow down the traffic. To work around this, we need to first identify the `fasttrack-connection` rule. ``` /ip firewall filter print ... 7 chain=forward action=fasttrack-connection connection-state=established,related log=no log-prefix="" ... ``` Once you have the ID of the existing `action=fasttrack-connection` rule, the following commands will insert two new rules just before it, which explicitly `accept` traffic to and from the guest network before they can be fasttrack'ed, causing them to feed through the queueing mechanism. Assuming the fasttrack rule's ID is `7`... ``` /ip firewall filter add place-before=7 copy-from=7 \ src-address=192.168.0.0/24 \ action=accept \ comment="FORWARD: skip fasttrack for traffic from guest network" add place-before=7 copy-from=7 \ dst-address=192.168.0.0/24 \ action=accept \ comment="FORWARD: skip fasttrack for traffic to guest network" ``` # Thanks Thanks to `mducharme` and ``Whiskey` `` on the `##mikrotik` Freenode IRC channel, for their advice and patience as I worked through this.